/*-------------------------------------------------------------------------
 *
 * stringinfo_mb.c
 *		多字节编码感知的附加 StringInfo 功能
 *
 * 这与 common/stringinfo.c 分开，以便该文件的前端用户
 * 无需引入不必要的多字节编码支持代码。
 *
 *
 * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
 * Portions Copyright (c) 1994, Regents of the University of California
 *
 * IDENTIFICATION
 *	  src/backend/utils/mb/stringinfo_mb.c
 *
 *-------------------------------------------------------------------------
 */
#include "postgres.h"

#include "mb/stringinfo_mb.h"
#include "mb/pg_wchar.h"


/*
 * appendStringInfoStringQuoted
 *
 * 从s到str最多追加maxlen字节，或如果maxlen < 0则追加整个输入字符串，
 * 在其周围添加单引号并双倍所有单引号。
 * 如果复制不完整，则添加省略号。
 */
void appendStringInfoStringQuoted(StringInfo fc_str, const char *fc_s, int fc_maxlen)
{
	char	   *fc_copy = NULL;
	const char *fc_chunk_search_start,
			   *fc_chunk_copy_start,
			   *fc_chunk_end;
	int			fc_slen;
	bool		fc_ellipsis;

	Assert(fc_str != NULL);

	fc_slen = strlen(fc_s);
	if (fc_maxlen >= 0 && fc_maxlen < fc_slen)
	{
		int			fc_finallen = pg_mbcliplen(fc_s, fc_slen, fc_maxlen);

		fc_copy = pnstrdup(fc_s, fc_finallen);
		fc_chunk_search_start = fc_copy;
		fc_chunk_copy_start = fc_copy;

		fc_ellipsis = true;
	}
	else
	{
		fc_chunk_search_start = fc_s;
		fc_chunk_copy_start = fc_s;

		fc_ellipsis = false;
	}

	appendStringInfoCharMacro(fc_str, '\'');

	while ((fc_chunk_end = strchr(fc_chunk_search_start, '\'')) != NULL)
	{
		/* 包括找到的分隔符'的副本 */
		appendBinaryStringInfoNT(fc_str,
								 fc_chunk_copy_start,
								 fc_chunk_end - fc_chunk_copy_start + 1);

		/* 为了双倍它，将这个'也包括在下一个块中 */
		fc_chunk_copy_start = fc_chunk_end;
		fc_chunk_search_start = fc_chunk_end + 1;
	}

	/* 复制最后的块并终止 */
	if (fc_ellipsis)
		appendStringInfo(fc_str, "%s...'", fc_chunk_copy_start);
	else
		appendStringInfo(fc_str, "%s'", fc_chunk_copy_start);

	if (fc_copy)
		pfree(fc_copy);
}
